define(function(require, exports, module) {
    var r20 = /%20/g,
        rbracket = /\[\]$/,
        rCRLF = /\r?\n/g,
        rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
        rsubmittable = /^(?:input|select|textarea|keygen)/i;

    function buildParams( prefix, obj, traditional, add ) {
        var name;

        if (obj instanceof Array) {
            // Serialize array item.
            // 数组分支
            for(i in obj){
                v = obj[i];
                if ( traditional || rbracket.test( prefix ) ) {
                    // Treat each array item as a scalar.
                    // 处理
                    add( prefix, v );

                } else {
                    // Item is non-scalar (array or object), encode its numeric index.
                    //反之参数key设置为 key[i] 循环调用自身，这时候循环中的自身会进入下一步
                    buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
                }
            }
            // jQuery.each( obj, function( i, v ) {
            //     // 如果第二个参数为真，则直接调用自身会生成类似 a=object  这样的数组
            //     // 或者参数为“数组”  key[0]或者key[name]
            // });

        } else if ( !traditional && typeof obj === "object" ) {
            //如果参数不为真，调用自身，进入第一步
            // Serialize object item.
            for ( name in obj ) {
                buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
            }

        } else {
            // Serialize scalar item.
            // 每项的操作
            add( prefix, obj );
        }
    }

    module.exports.stringify = function( a, traditional ) {
        var prefix,// 循环的键命名 for(var k in)  这里即k
            s = [],//返回的数据
            add = function( key, value ) {
                //key value对应循环中每项的name和值如：<input name="" value=""、{key:value}
                // 如果value是function，那么计算出返回值
                value = typeof value == 'function'  ? value() : ( value == null ? "" : value );
                //转为key1=value&key2=value2的形式
                s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
            };

        // Set traditional to true for jQuery <= 1.3.2 behavior.
        // 设置第二个参数，如果第二个参数等于undefined，取jQuery.ajaxSettings.traditional
        if ( traditional === undefined ) {
            traditional = false;
        }

        // If an array was passed in, assume that it is an array of form elements.
        // 第一个参数为数组或者表单的elements
        // 为数组或者jquery表单对象，不存在第二个参数的问题(a[]=1;a[]=2)
        //  || ( a.jquery && !jQuery.isPlainObject( a ) )
        if (a instanceof Array) {
            // Serialize the form elements
            // 循环取name与value
            // jQuery.each( a, function() {
            //     add( this.name, this.value );
            // });
            for(k in a){
                add( a[k].name, a[k].value );
            }

        } else {
            // If traditional, encode the "old" way (the way 1.3.2 or older
            // did it), otherwise encode params recursively.
            // 为对象的时候，需要照顾第二个参数，即深度
            for ( prefix in a ) {
                //调用另外一个方法，传入key，obj[k],深度,add回调方法
                buildParams( prefix, a[ prefix ], traditional, add );
            }
        }

        // Return the resulting serialization
        return s.join( "&" ).replace( r20, "+" );
    };
});